import { itemUp, itemDown, itemReplace, getId } from '@gnlab/utils'
import { type Word, type WordType } from '@/services/common/definition'

/**
 * 为每个 word 对象生成不重复的 id。
 * 用于渲染时作为 key，以避免用 array index 作为 key。
 * （因为那会导致 word 移动顺序、删除时，其他 word 被强制重新渲染，图片等都会重新加载，影响显示性能）
 */
const idMap = new WeakMap<Word, number>()
export function getWordId(word: Word) {
  if (!idMap.has(word)) idMap.set(word, getId())
  return idMap.get(word)!
}

export function useEdit(words: Word[], onChange: (words: Word[]) => void) {
  // ========== 列表编辑 ==========
  const { goUp, goDown, remove } = useMemo(
    () => ({
      goUp(index: number) {
        onChange(itemUp(words, index))
      },
      goDown(index: number) {
        onChange(itemDown(words, index))
      },
      remove(index: number) {
        const updated = [...words]
        updated.splice(index, 1)
        onChange(updated)
      },
    }),
    [words, onChange],
  )

  // ========== 内容编辑 ==========
  const [editing, setEditing] = useState<null | number | WordType>(null) // number: 正在编辑第几个 word； true: 正在新增 word

  const save = useCallback(
    (word: Word) => {
      if (editing === null) return
      onChange(typeof editing === 'number' ? itemReplace(words, editing, word) : [...words, word])
      setEditing(null)
    },
    [editing, words, onChange],
  )

  const cancel = useCallback(() => setEditing(null), [])

  return {
    goUp,
    goDown,
    remove,
    editing,
    setEditing,
    save,
    cancel,
  }
}
